static long do_sys_name_to_handle(const struct path *path,
                                  struct file_handle __user *ufh,
-                                 int __user *mnt_id)
+                                 int __user *mnt_id, int fh_flags)
 {
        long retval;
        struct file_handle f_handle;
        struct file_handle *handle = NULL;
 
        /*
-        * We need to make sure whether the file system
-        * support decoding of the file handle
+        * We need to make sure whether the file system support decoding of
+        * the file handle if decodeable file handle was requested.
+        * Otherwise, even empty export_operations are sufficient to opt-in
+        * to encoding FIDs.
         */
        if (!path->dentry->d_sb->s_export_op ||
-           !path->dentry->d_sb->s_export_op->fh_to_dentry)
+           (!(fh_flags & EXPORT_FH_FID) &&
+            !path->dentry->d_sb->s_export_op->fh_to_dentry))
                return -EOPNOTSUPP;
 
        if (copy_from_user(&f_handle, ufh, sizeof(struct file_handle)))
        /* convert handle size to multiple of sizeof(u32) */
        handle_dwords = f_handle.handle_bytes >> 2;
 
-       /* we ask for a non connected handle */
+       /* we ask for a non connectable maybe decodeable file handle */
        retval = exportfs_encode_fh(path->dentry,
                                    (struct fid *)handle->f_handle,
-                                   &handle_dwords,  0);
+                                   &handle_dwords, fh_flags);
        handle->handle_type = retval;
        /* convert handle size to bytes */
        handle_bytes = handle_dwords * sizeof(u32);
  * @handle: resulting file handle
  * @mnt_id: mount id of the file system containing the file
  * @flag: flag value to indicate whether to follow symlink or not
+ *        and whether a decodable file handle is required.
  *
  * @handle->handle_size indicate the space available to store the
  * variable part of the file handle in bytes. If there is not
 {
        struct path path;
        int lookup_flags;
+       int fh_flags;
        int err;
 
-       if ((flag & ~(AT_SYMLINK_FOLLOW | AT_EMPTY_PATH)) != 0)
+       if (flag & ~(AT_SYMLINK_FOLLOW | AT_EMPTY_PATH | AT_HANDLE_FID))
                return -EINVAL;
 
        lookup_flags = (flag & AT_SYMLINK_FOLLOW) ? LOOKUP_FOLLOW : 0;
+       fh_flags = (flag & AT_HANDLE_FID) ? EXPORT_FH_FID : 0;
        if (flag & AT_EMPTY_PATH)
                lookup_flags |= LOOKUP_EMPTY;
        err = user_path_at(dfd, name, lookup_flags, &path);
        if (!err) {
-               err = do_sys_name_to_handle(&path, handle, mnt_id);
+               err = do_sys_name_to_handle(&path, handle, mnt_id, fh_flags);
                path_put(&path);
        }
        return err;