/*
  * find_inode - resolve a user-given path to a specific inode and return a nd
  */
-static int find_inode(const char __user *dirname, struct nameidata *nd)
+static int find_inode(const char __user *dirname, struct nameidata *nd,
+                     unsigned flags)
 {
        int error;
 
-       error = __user_walk(dirname, LOOKUP_FOLLOW, nd);
+       error = __user_walk(dirname, flags, nd);
        if (error)
                return error;
        /* you can only watch an inode if you have read permissions on it */
        struct file *filp;
        int ret, fput_needed;
        int mask_add = 0;
+       unsigned flags = 0;
 
        filp = fget_light(fd, &fput_needed);
        if (unlikely(!filp))
                goto fput_and_out;
        }
 
-       ret = find_inode(path, &nd);
+       if (!(mask & IN_DONT_FOLLOW))
+               flags |= LOOKUP_FOLLOW;
+       if (mask & IN_ONLYDIR)
+               flags |= LOOKUP_DIRECTORY;
+
+       ret = find_inode(path, &nd, flags);
        if (unlikely(ret))
                goto fput_and_out;
 
 
 #define IN_MOVE                        (IN_MOVED_FROM | IN_MOVED_TO) /* moves */
 
 /* special flags */
+#define IN_ONLYDIR             0x01000000      /* only watch the path if it is a directory */
+#define IN_DONT_FOLLOW         0x02000000      /* don't follow a sym link */
 #define IN_MASK_ADD            0x20000000      /* add to the mask of an already existing watch */
 #define IN_ISDIR               0x40000000      /* event occurred against dir */
 #define IN_ONESHOT             0x80000000      /* only send event once */