Patch "udf: Fix loading of special inodes" has been added to the 3.17-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    udf: Fix loading of special inodes

to the 3.17-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     udf-fix-loading-of-special-inodes.patch
and it can be found in the queue-3.17 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.


>From 6174c2eb8ecef271159bdcde460ce8af54d8f72f Mon Sep 17 00:00:00 2001
From: Jan Kara <jack@xxxxxxx>
Date: Thu, 9 Oct 2014 12:52:16 +0200
Subject: udf: Fix loading of special inodes

From: Jan Kara <jack@xxxxxxx>

commit 6174c2eb8ecef271159bdcde460ce8af54d8f72f upstream.

Some UDF media have special inodes (like VAT or metadata partition
inodes) whose link_count is 0. Thus commit 4071b9136223 (udf: Properly
detect stale inodes) broke loading these inodes because udf_iget()
started returning -ESTALE for them. Since we still need to properly
detect stale inodes queried by NFS, create two variants of udf_iget() -
one which is used for looking up special inodes (which ignores
link_count == 0) and one which is used for other cases which return
ESTALE when link_count == 0.

Fixes: 4071b913622316970d0e1919f7d82b4403fec5f2
Signed-off-by: Jan Kara <jack@xxxxxxx>
Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>

---
 fs/udf/inode.c   |   14 +++++++++-----
 fs/udf/super.c   |   10 +++++-----
 fs/udf/udfdecl.h |   13 ++++++++++++-
 3 files changed, 26 insertions(+), 11 deletions(-)

--- a/fs/udf/inode.c
+++ b/fs/udf/inode.c
@@ -1277,7 +1277,7 @@ update_time:
  */
 #define UDF_MAX_ICB_NESTING 1024
 
-static int udf_read_inode(struct inode *inode)
+static int udf_read_inode(struct inode *inode, bool hidden_inode)
 {
 	struct buffer_head *bh = NULL;
 	struct fileEntry *fe;
@@ -1436,8 +1436,11 @@ reread:
 
 	link_count = le16_to_cpu(fe->fileLinkCount);
 	if (!link_count) {
-		ret = -ESTALE;
-		goto out;
+		if (!hidden_inode) {
+			ret = -ESTALE;
+			goto out;
+		}
+		link_count = 1;
 	}
 	set_nlink(inode, link_count);
 
@@ -1826,7 +1829,8 @@ out:
 	return err;
 }
 
-struct inode *udf_iget(struct super_block *sb, struct kernel_lb_addr *ino)
+struct inode *__udf_iget(struct super_block *sb, struct kernel_lb_addr *ino,
+			 bool hidden_inode)
 {
 	unsigned long block = udf_get_lb_pblock(sb, ino, 0);
 	struct inode *inode = iget_locked(sb, block);
@@ -1839,7 +1843,7 @@ struct inode *udf_iget(struct super_bloc
 		return inode;
 
 	memcpy(&UDF_I(inode)->i_location, ino, sizeof(struct kernel_lb_addr));
-	err = udf_read_inode(inode);
+	err = udf_read_inode(inode, hidden_inode);
 	if (err < 0) {
 		iget_failed(inode);
 		return ERR_PTR(err);
--- a/fs/udf/super.c
+++ b/fs/udf/super.c
@@ -959,7 +959,7 @@ struct inode *udf_find_metadata_inode_ef
 	addr.logicalBlockNum = meta_file_loc;
 	addr.partitionReferenceNum = partition_num;
 
-	metadata_fe = udf_iget(sb, &addr);
+	metadata_fe = udf_iget_special(sb, &addr);
 
 	if (IS_ERR(metadata_fe)) {
 		udf_warn(sb, "metadata inode efe not found\n");
@@ -1020,7 +1020,7 @@ static int udf_load_metadata_files(struc
 		udf_debug("Bitmap file location: block = %d part = %d\n",
 			  addr.logicalBlockNum, addr.partitionReferenceNum);
 
-		fe = udf_iget(sb, &addr);
+		fe = udf_iget_special(sb, &addr);
 		if (IS_ERR(fe)) {
 			if (sb->s_flags & MS_RDONLY)
 				udf_warn(sb, "bitmap inode efe not found but it's ok since the disc is mounted read-only\n");
@@ -1119,7 +1119,7 @@ static int udf_fill_partdesc_info(struct
 		};
 		struct inode *inode;
 
-		inode = udf_iget(sb, &loc);
+		inode = udf_iget_special(sb, &loc);
 		if (IS_ERR(inode)) {
 			udf_debug("cannot load unallocSpaceTable (part %d)\n",
 				  p_index);
@@ -1154,7 +1154,7 @@ static int udf_fill_partdesc_info(struct
 		};
 		struct inode *inode;
 
-		inode = udf_iget(sb, &loc);
+		inode = udf_iget_special(sb, &loc);
 		if (IS_ERR(inode)) {
 			udf_debug("cannot load freedSpaceTable (part %d)\n",
 				  p_index);
@@ -1198,7 +1198,7 @@ static void udf_find_vat_block(struct su
 	     vat_block >= map->s_partition_root &&
 	     vat_block >= start_block - 3; vat_block--) {
 		ino.logicalBlockNum = vat_block - map->s_partition_root;
-		inode = udf_iget(sb, &ino);
+		inode = udf_iget_special(sb, &ino);
 		if (!IS_ERR(inode)) {
 			sbi->s_vat_inode = inode;
 			break;
--- a/fs/udf/udfdecl.h
+++ b/fs/udf/udfdecl.h
@@ -138,7 +138,18 @@ extern int udf_write_fi(struct inode *in
 /* file.c */
 extern long udf_ioctl(struct file *, unsigned int, unsigned long);
 /* inode.c */
-extern struct inode *udf_iget(struct super_block *, struct kernel_lb_addr *);
+extern struct inode *__udf_iget(struct super_block *, struct kernel_lb_addr *,
+				bool hidden_inode);
+static inline struct inode *udf_iget_special(struct super_block *sb,
+					     struct kernel_lb_addr *ino)
+{
+	return __udf_iget(sb, ino, true);
+}
+static inline struct inode *udf_iget(struct super_block *sb,
+				     struct kernel_lb_addr *ino)
+{
+	return __udf_iget(sb, ino, false);
+}
 extern int udf_expand_file_adinicb(struct inode *);
 extern struct buffer_head *udf_expand_dir_adinicb(struct inode *, int *, int *);
 extern struct buffer_head *udf_bread(struct inode *, int, int, int *);


Patches currently in stable-queue which might be from jack@xxxxxxx are

queue-3.17/fanotify-enable-close-on-exec-on-events-fd-when-requested-in-fanotify_init.patch
queue-3.17/udf-fix-loading-of-special-inodes.patch
--
To unsubscribe from this list: send the line "unsubscribe stable" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Kernel]     [Kernel Development Newbies]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]