}
EXPORT_SYMBOL_GPL(generic_encode_ino32_fh);
+#define FILEID_INO64_GEN_LEN 3
+
+/**
+ * exportfs_encode_ino64_fid - encode non-decodeable 64bit ino file id
+ * @inode: the object to encode
+ * @fid: where to store the file handle fragment
+ * @max_len: maximum length to store there (in 4 byte units)
+ *
+ * This generic function is used to encode a non-decodeable file id for
+ * fanotify for filesystems that do not support NFS export.
+ */
+static int exportfs_encode_ino64_fid(struct inode *inode, struct fid *fid,
+ int *max_len)
+{
+ if (*max_len < FILEID_INO64_GEN_LEN) {
+ *max_len = FILEID_INO64_GEN_LEN;
+ return FILEID_INVALID;
+ }
+
+ fid->i64.ino = inode->i_ino;
+ fid->i64.gen = inode->i_generation;
+ *max_len = FILEID_INO64_GEN_LEN;
+
+ return FILEID_INO64_GEN;
+}
+
/**
* exportfs_encode_inode_fh - encode a file handle from inode
* @inode: the object to encode
if (!exportfs_can_encode_fh(nop, flags))
return -EOPNOTSUPP;
- if (nop && nop->encode_fh)
- return nop->encode_fh(inode, fid->raw, max_len, parent);
+ if (!nop && (flags & EXPORT_FH_FID))
+ return exportfs_encode_ino64_fid(inode, fid, max_len);
- return -EOPNOTSUPP;
+ return nop->encode_fh(inode, fid->raw, max_len, parent);
}
EXPORT_SYMBOL_GPL(exportfs_encode_inode_fh);
u32 parent_ino;
u32 parent_gen;
} i32;
- struct {
+ struct {
+ u64 ino;
+ u32 gen;
+ } __packed i64;
+ struct {
u32 block;
u16 partref;
u16 parent_partref;
static inline bool exportfs_can_encode_fid(const struct export_operations *nop)
{
- return nop && nop->encode_fh;
+ return !nop || nop->encode_fh;
}
static inline bool exportfs_can_decode_fh(const struct export_operations *nop)
{
/*
* If a non-decodeable file handle was requested, we only need to make
- * sure that filesystem can encode file handles.
+ * sure that filesystem did not opt-out of encoding fid.
*/
if (fh_flags & EXPORT_FH_FID)
return exportfs_can_encode_fid(nop);