|
@@ -152,9 +152,39 @@ out_unmap:
|
|
|
return err;
|
|
|
}
|
|
|
|
|
|
+static int udf_symlink_getattr(struct vfsmount *mnt, struct dentry *dentry,
|
|
|
+ struct kstat *stat)
|
|
|
+{
|
|
|
+ struct inode *inode = d_backing_inode(dentry);
|
|
|
+ struct page *page;
|
|
|
+
|
|
|
+ generic_fillattr(inode, stat);
|
|
|
+ page = read_mapping_page(inode->i_mapping, 0, NULL);
|
|
|
+ if (IS_ERR(page))
|
|
|
+ return PTR_ERR(page);
|
|
|
+ /*
|
|
|
+ * UDF uses non-trivial encoding of symlinks so i_size does not match
|
|
|
+ * number of characters reported by readlink(2) which apparently some
|
|
|
+ * applications expect. Also POSIX says that "The value returned in the
|
|
|
+ * st_size field shall be the length of the contents of the symbolic
|
|
|
+ * link, and shall not count a trailing null if one is present." So
|
|
|
+ * let's report the length of string returned by readlink(2) for
|
|
|
+ * st_size.
|
|
|
+ */
|
|
|
+ stat->size = strlen(page_address(page));
|
|
|
+ put_page(page);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* symlinks can't do much...
|
|
|
*/
|
|
|
const struct address_space_operations udf_symlink_aops = {
|
|
|
.readpage = udf_symlink_filler,
|
|
|
};
|
|
|
+
|
|
|
+const struct inode_operations udf_symlink_inode_operations = {
|
|
|
+ .get_link = page_get_link,
|
|
|
+ .getattr = udf_symlink_getattr,
|
|
|
+};
|