- patches.apparmor/remove_suid_new_case_in_2.6.22.diff: Merge fix.
[linux-flexiantxendom0-3.2.10.git] / fs / proc / base.c
index 1bdee99..a5fa1fd 100644 (file)
@@ -61,9 +61,9 @@
 #include <linux/namei.h>
 #include <linux/mnt_namespace.h>
 #include <linux/mm.h>
-#include <linux/smp_lock.h>
 #include <linux/rcupdate.h>
 #include <linux/kallsyms.h>
+#include <linux/module.h>
 #include <linux/mount.h>
 #include <linux/security.h>
 #include <linux/ptrace.h>
@@ -90,8 +90,8 @@
 #define PROC_NUMBUF 13
 
 struct pid_entry {
-       int len;
        char *name;
+       int len;
        mode_t mode;
        const struct inode_operations *iop;
        const struct file_operations *fop;
@@ -99,8 +99,8 @@ struct pid_entry {
 };
 
 #define NOD(NAME, MODE, IOP, FOP, OP) {                        \
-       .len  = sizeof(NAME) - 1,                       \
        .name = (NAME),                                 \
+       .len  = sizeof(NAME) - 1,                       \
        .mode = MODE,                                   \
        .iop  = IOP,                                    \
        .fop  = FOP,                                    \
@@ -123,6 +123,9 @@ struct pid_entry {
                NULL, &proc_info_file_operations,       \
                { .proc_read = &proc_##OTYPE } )
 
+int maps_protect;
+EXPORT_SYMBOL(maps_protect);
+
 static struct fs_struct *get_fs_struct(struct task_struct *task)
 {
        struct fs_struct *fs;
@@ -275,17 +278,15 @@ static int proc_pid_auxv(struct task_struct *task, char *buffer)
  */
 static int proc_pid_wchan(struct task_struct *task, char *buffer)
 {
-       char *modname;
-       const char *sym_name;
-       unsigned long wchan, size, offset;
-       char namebuf[KSYM_NAME_LEN+1];
+       unsigned long wchan;
+       char symname[KSYM_NAME_LEN+1];
 
        wchan = get_wchan(task);
 
-       sym_name = kallsyms_lookup(wchan, &size, &offset, &modname, namebuf);
-       if (sym_name)
-               return sprintf(buffer, "%s", sym_name);
-       return sprintf(buffer, "%lu", wchan);
+       if (lookup_symbol_name(wchan, symname) < 0)
+               return sprintf(buffer, "%lu", wchan);
+       else
+               return sprintf(buffer, "%s", symname);
 }
 #endif /* CONFIG_KALLSYMS */
 
@@ -310,7 +311,9 @@ static int proc_oom_score(struct task_struct *task, char *buffer)
        struct timespec uptime;
 
        do_posix_clock_monotonic_gettime(&uptime);
+       read_lock(&tasklist_lock);
        points = badness(task, uptime.tv_sec);
+       read_unlock(&tasklist_lock);
        return sprintf(buffer, "%lu\n", points);
 }
 
@@ -657,7 +660,6 @@ static ssize_t oom_adjust_read(struct file *file, char __user *buf,
        char buffer[PROC_NUMBUF];
        size_t len;
        int oom_adjust;
-       loff_t __ppos = *ppos;
 
        if (!task)
                return -ESRCH;
@@ -665,14 +667,8 @@ static ssize_t oom_adjust_read(struct file *file, char __user *buf,
        put_task_struct(task);
 
        len = snprintf(buffer, sizeof(buffer), "%i\n", oom_adjust);
-       if (__ppos >= len)
-               return 0;
-       if (count > len-__ppos)
-               count = len-__ppos;
-       if (copy_to_user(buf, buffer + __ppos, count))
-               return -EFAULT;
-       *ppos = __ppos + count;
-       return count;
+
+       return simple_read_from_buffer(buf, count, ppos, buffer, len);
 }
 
 static ssize_t oom_adjust_write(struct file *file, const char __user *buf,
@@ -712,6 +708,42 @@ static const struct file_operations proc_oom_adjust_operations = {
        .write          = oom_adjust_write,
 };
 
+#ifdef CONFIG_MMU
+static ssize_t clear_refs_write(struct file *file, const char __user *buf,
+                               size_t count, loff_t *ppos)
+{
+       struct task_struct *task;
+       char buffer[PROC_NUMBUF], *end;
+       struct mm_struct *mm;
+
+       memset(buffer, 0, sizeof(buffer));
+       if (count > sizeof(buffer) - 1)
+               count = sizeof(buffer) - 1;
+       if (copy_from_user(buffer, buf, count))
+               return -EFAULT;
+       if (!simple_strtol(buffer, &end, 0))
+               return -EINVAL;
+       if (*end == '\n')
+               end++;
+       task = get_proc_task(file->f_path.dentry->d_inode);
+       if (!task)
+               return -ESRCH;
+       mm = get_task_mm(task);
+       if (mm) {
+               clear_refs_smap(mm);
+               mmput(mm);
+       }
+       put_task_struct(task);
+       if (end - buffer == 0)
+               return -EIO;
+       return end - buffer;
+}
+
+static struct file_operations proc_clear_refs_operations = {
+       .write          = clear_refs_write,
+};
+#endif
+
 #ifdef CONFIG_AUDITSYSCALL
 #define TMPBUFLEN 21
 static ssize_t proc_loginuid_read(struct file * file, char __user * buf,
@@ -786,7 +818,6 @@ static ssize_t seccomp_read(struct file *file, char __user *buf,
 {
        struct task_struct *tsk = get_proc_task(file->f_dentry->d_inode);
        char __buf[20];
-       loff_t __ppos = *ppos;
        size_t len;
 
        if (!tsk)
@@ -794,14 +825,8 @@ static ssize_t seccomp_read(struct file *file, char __user *buf,
        /* no need to print the trailing zero, so use only len */
        len = sprintf(__buf, "%u\n", tsk->seccomp.mode);
        put_task_struct(tsk);
-       if (__ppos >= len)
-               return 0;
-       if (count > len - __ppos)
-               count = len - __ppos;
-       if (copy_to_user(buf, __buf + __ppos, count))
-               return -EFAULT;
-       *ppos = __ppos + count;
-       return count;
+
+       return simple_read_from_buffer(buf, count, ppos, __buf, len);
 }
 
 static ssize_t seccomp_write(struct file *file, const char __user *buf,
@@ -860,7 +885,6 @@ static ssize_t proc_fault_inject_read(struct file * file, char __user * buf,
        char buffer[PROC_NUMBUF];
        size_t len;
        int make_it_fail;
-       loff_t __ppos = *ppos;
 
        if (!task)
                return -ESRCH;
@@ -868,14 +892,8 @@ static ssize_t proc_fault_inject_read(struct file * file, char __user * buf,
        put_task_struct(task);
 
        len = snprintf(buffer, sizeof(buffer), "%i\n", make_it_fail);
-       if (__ppos >= len)
-               return 0;
-       if (count > len-__ppos)
-               count = len-__ppos;
-       if (copy_to_user(buf, buffer + __ppos, count))
-               return -EFAULT;
-       *ppos = __ppos + count;
-       return count;
+
+       return simple_read_from_buffer(buf, count, ppos, buffer, len);
 }
 
 static ssize_t proc_fault_inject_write(struct file * file,
@@ -938,7 +956,7 @@ static int do_proc_readlink(struct dentry *dentry, struct vfsmount *mnt,
 
        if (!tmp)
                return -ENOMEM;
-               
+
        inode = dentry->d_inode;
        path = d_path(dentry, mnt, tmp, PAGE_SIZE);
        len = PTR_ERR(path);
@@ -1118,7 +1136,8 @@ static struct dentry_operations pid_dentry_operations =
 
 /* Lookups */
 
-typedef struct dentry *instantiate_t(struct inode *, struct dentry *, struct task_struct *, void *);
+typedef struct dentry *instantiate_t(struct inode *, struct dentry *,
+                               struct task_struct *, const void *);
 
 /*
  * Fill a directory entry.
@@ -1134,7 +1153,7 @@ typedef struct dentry *instantiate_t(struct inode *, struct dentry *, struct tas
  */
 static int proc_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
        char *name, int len,
-       instantiate_t instantiate, struct task_struct *task, void *ptr)
+       instantiate_t instantiate, struct task_struct *task, const void *ptr)
 {
        struct dentry *child, *dir = filp->f_path.dentry;
        struct inode *inode;
@@ -1196,7 +1215,10 @@ out:
        return ~0U;
 }
 
-static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt)
+#define PROC_FDINFO_MAX 64
+
+static int proc_fd_info(struct inode *inode, struct dentry **dentry,
+                       struct vfsmount **mnt, char *info)
 {
        struct task_struct *task = get_proc_task(inode);
        struct files_struct *files = NULL;
@@ -1215,8 +1237,16 @@ static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsm
                spin_lock(&files->file_lock);
                file = fcheck_files(files, fd);
                if (file) {
-                       *mnt = mntget(file->f_path.mnt);
-                       *dentry = dget(file->f_path.dentry);
+                       if (mnt)
+                               *mnt = mntget(file->f_path.mnt);
+                       if (dentry)
+                               *dentry = dget(file->f_path.dentry);
+                       if (info)
+                               snprintf(info, PROC_FDINFO_MAX,
+                                        "pos:\t%lli\n"
+                                        "flags:\t0%o\n",
+                                        (long long) file->f_pos,
+                                        file->f_flags);
                        spin_unlock(&files->file_lock);
                        put_files_struct(files);
                        return 0;
@@ -1227,6 +1257,12 @@ static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsm
        return -ENOENT;
 }
 
+static int proc_fd_link(struct inode *inode, struct dentry **dentry,
+                       struct vfsmount **mnt)
+{
+       return proc_fd_info(inode, dentry, mnt, NULL);
+}
+
 static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd)
 {
        struct inode *inode = dentry->d_inode;
@@ -1269,9 +1305,9 @@ static struct dentry_operations tid_fd_dentry_operations =
 };
 
 static struct dentry *proc_fd_instantiate(struct inode *dir,
-       struct dentry *dentry, struct task_struct *task, void *ptr)
+       struct dentry *dentry, struct task_struct *task, const void *ptr)
 {
-       unsigned fd = *(unsigned *)ptr;
+       unsigned fd = *(const unsigned *)ptr;
        struct file *file;
        struct files_struct *files;
        struct inode *inode;
@@ -1322,7 +1358,9 @@ out_iput:
        goto out;
 }
 
-static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry, struct nameidata *nd)
+static struct dentry *proc_lookupfd_common(struct inode *dir,
+                                          struct dentry *dentry,
+                                          instantiate_t instantiate)
 {
        struct task_struct *task = get_proc_task(dir);
        unsigned fd = name_to_int(dentry);
@@ -1333,23 +1371,15 @@ static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry,
        if (fd == ~0U)
                goto out;
 
-       result = proc_fd_instantiate(dir, dentry, task, &fd);
+       result = instantiate(dir, dentry, task, &fd);
 out:
        put_task_struct(task);
 out_no_task:
        return result;
 }
 
-static int proc_fd_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
-       struct task_struct *task, int fd)
-{
-       char name[PROC_NUMBUF];
-       int len = snprintf(name, sizeof(name), "%d", fd);
-       return proc_fill_cache(filp, dirent, filldir, name, len,
-                               proc_fd_instantiate, task, &fd);
-}
-
-static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir)
+static int proc_readfd_common(struct file * filp, void * dirent,
+                             filldir_t filldir, instantiate_t instantiate)
 {
        struct dentry *dentry = filp->f_path.dentry;
        struct inode *inode = dentry->d_inode;
@@ -1385,12 +1415,17 @@ static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir)
                        for (fd = filp->f_pos-2;
                             fd < fdt->max_fds;
                             fd++, filp->f_pos++) {
+                               char name[PROC_NUMBUF];
+                               int len;
 
                                if (!fcheck_files(files, fd))
                                        continue;
                                rcu_read_unlock();
 
-                               if (proc_fd_fill_cache(filp, dirent, filldir, p, fd) < 0) {
+                               len = snprintf(name, sizeof(name), "%d", fd);
+                               if (proc_fill_cache(filp, dirent, filldir,
+                                                   name, len, instantiate,
+                                                   p, &fd) < 0) {
                                        rcu_read_lock();
                                        break;
                                }
@@ -1405,23 +1440,119 @@ out_no_task:
        return retval;
 }
 
+static struct dentry *proc_lookupfd(struct inode *dir, struct dentry *dentry,
+                                   struct nameidata *nd)
+{
+       return proc_lookupfd_common(dir, dentry, proc_fd_instantiate);
+}
+
+static int proc_readfd(struct file *filp, void *dirent, filldir_t filldir)
+{
+       return proc_readfd_common(filp, dirent, filldir, proc_fd_instantiate);
+}
+
+static ssize_t proc_fdinfo_read(struct file *file, char __user *buf,
+                                     size_t len, loff_t *ppos)
+{
+       char tmp[PROC_FDINFO_MAX];
+       int err = proc_fd_info(file->f_path.dentry->d_inode, NULL, NULL, tmp);
+       if (!err)
+               err = simple_read_from_buffer(buf, len, ppos, tmp, strlen(tmp));
+       return err;
+}
+
+static const struct file_operations proc_fdinfo_file_operations = {
+       .open           = nonseekable_open,
+       .read           = proc_fdinfo_read,
+};
+
 static const struct file_operations proc_fd_operations = {
        .read           = generic_read_dir,
        .readdir        = proc_readfd,
 };
 
 /*
+ * /proc/pid/fd needs a special permission handler so that a process can still
+ * access /proc/self/fd after it has executed a setuid().
+ */
+static int proc_fd_permission(struct inode *inode, int mask,
+                               struct nameidata *nd)
+{
+       int rv;
+
+       rv = generic_permission(inode, mask, NULL);
+       if (rv == 0)
+               return 0;
+       if (task_pid(current) == proc_pid(inode))
+               rv = 0;
+       return rv;
+}
+
+/*
  * proc directories can do almost nothing..
  */
 static const struct inode_operations proc_fd_inode_operations = {
        .lookup         = proc_lookupfd,
+       .permission     = proc_fd_permission,
+       .setattr        = proc_setattr,
+};
+
+static struct dentry *proc_fdinfo_instantiate(struct inode *dir,
+       struct dentry *dentry, struct task_struct *task, const void *ptr)
+{
+       unsigned fd = *(unsigned *)ptr;
+       struct inode *inode;
+       struct proc_inode *ei;
+       struct dentry *error = ERR_PTR(-ENOENT);
+
+       inode = proc_pid_make_inode(dir->i_sb, task);
+       if (!inode)
+               goto out;
+       ei = PROC_I(inode);
+       ei->fd = fd;
+       inode->i_mode = S_IFREG | S_IRUSR;
+       inode->i_fop = &proc_fdinfo_file_operations;
+       dentry->d_op = &tid_fd_dentry_operations;
+       d_add(dentry, inode);
+       /* Close the race of the process dying before we return the dentry */
+       if (tid_fd_revalidate(dentry, NULL))
+               error = NULL;
+
+ out:
+       return error;
+}
+
+static struct dentry *proc_lookupfdinfo(struct inode *dir,
+                                       struct dentry *dentry,
+                                       struct nameidata *nd)
+{
+       return proc_lookupfd_common(dir, dentry, proc_fdinfo_instantiate);
+}
+
+static int proc_readfdinfo(struct file *filp, void *dirent, filldir_t filldir)
+{
+       return proc_readfd_common(filp, dirent, filldir,
+                                 proc_fdinfo_instantiate);
+}
+
+static const struct file_operations proc_fdinfo_operations = {
+       .read           = generic_read_dir,
+       .readdir        = proc_readfdinfo,
+};
+
+/*
+ * proc directories can do almost nothing..
+ */
+static const struct inode_operations proc_fdinfo_inode_operations = {
+       .lookup         = proc_lookupfdinfo,
        .setattr        = proc_setattr,
 };
 
+
 static struct dentry *proc_pident_instantiate(struct inode *dir,
-       struct dentry *dentry, struct task_struct *task, void *ptr)
+       struct dentry *dentry, struct task_struct *task, const void *ptr)
 {
-       struct pid_entry *p = ptr;
+       const struct pid_entry *p = ptr;
        struct inode *inode;
        struct proc_inode *ei;
        struct dentry *error = ERR_PTR(-EINVAL);
@@ -1450,13 +1581,13 @@ out:
 
 static struct dentry *proc_pident_lookup(struct inode *dir, 
                                         struct dentry *dentry,
-                                        struct pid_entry *ents,
+                                        const struct pid_entry *ents,
                                         unsigned int nents)
 {
        struct inode *inode;
        struct dentry *error;
        struct task_struct *task = get_proc_task(dir);
-       struct pid_entry *p, *last;
+       const struct pid_entry *p, *last;
 
        error = ERR_PTR(-ENOENT);
        inode = NULL;
@@ -1485,8 +1616,8 @@ out_no_task:
        return error;
 }
 
-static int proc_pident_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
-       struct task_struct *task, struct pid_entry *p)
+static int proc_pident_fill_cache(struct file *filp, void *dirent,
+       filldir_t filldir, struct task_struct *task, const struct pid_entry *p)
 {
        return proc_fill_cache(filp, dirent, filldir, p->name, p->len,
                                proc_pident_instantiate, task, p);
@@ -1494,14 +1625,14 @@ static int proc_pident_fill_cache(struct file *filp, void *dirent, filldir_t fil
 
 static int proc_pident_readdir(struct file *filp,
                void *dirent, filldir_t filldir,
-               struct pid_entry *ents, unsigned int nents)
+               const struct pid_entry *ents, unsigned int nents)
 {
        int i;
        int pid;
        struct dentry *dentry = filp->f_path.dentry;
        struct inode *inode = dentry->d_inode;
        struct task_struct *task = get_proc_task(inode);
-       struct pid_entry *p, *last;
+       const struct pid_entry *p, *last;
        ino_t ino;
        int ret;
 
@@ -1616,7 +1747,7 @@ static const struct file_operations proc_pid_attr_operations = {
        .write          = proc_pid_attr_write,
 };
 
-static struct pid_entry attr_dir_stuff[] = {
+static const struct pid_entry attr_dir_stuff[] = {
        REG("current",    S_IRUGO|S_IWUGO, pid_attr),
        REG("prev",       S_IRUGO,         pid_attr),
        REG("exec",       S_IRUGO|S_IWUGO, pid_attr),
@@ -1682,7 +1813,7 @@ static const struct inode_operations proc_self_inode_operations = {
  * that properly belong to the /proc filesystem, as they describe
  * describe something that is process related.
  */
-static struct pid_entry proc_base_stuff[] = {
+static const struct pid_entry proc_base_stuff[] = {
        NOD("self", S_IFLNK|S_IRWXUGO,
                &proc_self_inode_operations, NULL, {}),
 };
@@ -1711,9 +1842,9 @@ static struct dentry_operations proc_base_dentry_operations =
 };
 
 static struct dentry *proc_base_instantiate(struct inode *dir,
-       struct dentry *dentry, struct task_struct *task, void *ptr)
+       struct dentry *dentry, struct task_struct *task, const void *ptr)
 {
-       struct pid_entry *p = ptr;
+       const struct pid_entry *p = ptr;
        struct inode *inode;
        struct proc_inode *ei;
        struct dentry *error = ERR_PTR(-EINVAL);
@@ -1761,7 +1892,7 @@ static struct dentry *proc_base_lookup(struct inode *dir, struct dentry *dentry)
 {
        struct dentry *error;
        struct task_struct *task = get_proc_task(dir);
-       struct pid_entry *p, *last;
+       const struct pid_entry *p, *last;
 
        error = ERR_PTR(-ENOENT);
 
@@ -1787,8 +1918,8 @@ out_no_task:
        return error;
 }
 
-static int proc_base_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
-       struct task_struct *task, struct pid_entry *p)
+static int proc_base_fill_cache(struct file *filp, void *dirent,
+       filldir_t filldir, struct task_struct *task, const struct pid_entry *p)
 {
        return proc_fill_cache(filp, dirent, filldir, p->name, p->len,
                                proc_base_instantiate, task, p);
@@ -1825,9 +1956,10 @@ static int proc_pid_io_accounting(struct task_struct *task, char *buffer)
 static const struct file_operations proc_task_operations;
 static const struct inode_operations proc_task_inode_operations;
 
-static struct pid_entry tgid_base_stuff[] = {
+static const struct pid_entry tgid_base_stuff[] = {
        DIR("task",       S_IRUGO|S_IXUGO, task),
        DIR("fd",         S_IRUSR|S_IXUSR, fd),
+       DIR("fdinfo",     S_IRUSR|S_IXUSR, fdinfo),
        INF("environ",    S_IRUSR, pid_environ),
        INF("auxv",       S_IRUSR, pid_auxv),
        INF("status",     S_IRUGO, pid_status),
@@ -1848,6 +1980,7 @@ static struct pid_entry tgid_base_stuff[] = {
        REG("mounts",     S_IRUGO, mounts),
        REG("mountstats", S_IRUSR, mountstats),
 #ifdef CONFIG_MMU
+       REG("clear_refs", S_IWUSR, clear_refs),
        REG("smaps",      S_IRUGO, smaps),
 #endif
 #ifdef CONFIG_SECURITY
@@ -1967,7 +2100,7 @@ out:
 
 static struct dentry *proc_pid_instantiate(struct inode *dir,
                                           struct dentry * dentry,
-                                          struct task_struct *task, void *ptr)
+                                          struct task_struct *task, const void *ptr)
 {
        struct dentry *error = ERR_PTR(-ENOENT);
        struct inode *inode;
@@ -1980,7 +2113,7 @@ static struct dentry *proc_pid_instantiate(struct inode *dir,
        inode->i_op = &proc_tgid_base_inode_operations;
        inode->i_fop = &proc_tgid_base_operations;
        inode->i_flags|=S_IMMUTABLE;
-       inode->i_nlink = 4;
+       inode->i_nlink = 5;
 #ifdef CONFIG_SECURITY
        inode->i_nlink += 1;
 #endif
@@ -2082,7 +2215,7 @@ int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir)
                goto out_no_task;
 
        for (; nr < ARRAY_SIZE(proc_base_stuff); filp->f_pos++, nr++) {
-               struct pid_entry *p = &proc_base_stuff[nr];
+               const struct pid_entry *p = &proc_base_stuff[nr];
                if (proc_base_fill_cache(filp, dirent, filldir, reaper, p) < 0)
                        goto out;
        }
@@ -2108,8 +2241,9 @@ out_no_task:
 /*
  * Tasks
  */
-static struct pid_entry tid_base_stuff[] = {
+static const struct pid_entry tid_base_stuff[] = {
        DIR("fd",        S_IRUSR|S_IXUSR, fd),
+       DIR("fdinfo",    S_IRUSR|S_IXUSR, fdinfo),
        INF("environ",   S_IRUSR, pid_environ),
        INF("auxv",      S_IRUSR, pid_auxv),
        INF("status",    S_IRUGO, pid_status),
@@ -2129,6 +2263,7 @@ static struct pid_entry tid_base_stuff[] = {
        LNK("exe",       exe),
        REG("mounts",    S_IRUGO, mounts),
 #ifdef CONFIG_MMU
+       REG("clear_refs", S_IWUSR, clear_refs),
        REG("smaps",     S_IRUGO, smaps),
 #endif
 #ifdef CONFIG_SECURITY
@@ -2177,7 +2312,7 @@ static const struct inode_operations proc_tid_base_inode_operations = {
 };
 
 static struct dentry *proc_task_instantiate(struct inode *dir,
-       struct dentry *dentry, struct task_struct *task, void *ptr)
+       struct dentry *dentry, struct task_struct *task, const void *ptr)
 {
        struct dentry *error = ERR_PTR(-ENOENT);
        struct inode *inode;
@@ -2189,7 +2324,7 @@ static struct dentry *proc_task_instantiate(struct inode *dir,
        inode->i_op = &proc_tid_base_inode_operations;
        inode->i_fop = &proc_tid_base_operations;
        inode->i_flags|=S_IMMUTABLE;
-       inode->i_nlink = 3;
+       inode->i_nlink = 4;
 #ifdef CONFIG_SECURITY
        inode->i_nlink += 1;
 #endif