You are viewing a plain text version of this content. The canonical link for it is here.
Posted to hdfs-commits@hadoop.apache.org by cn...@apache.org on 2014/05/16 08:06:11 UTC

svn commit: r1595113 - in /hadoop/common/branches/HDFS-2006/hadoop-hdfs-project/hadoop-hdfs: ./ src/main/java/org/apache/hadoop/hdfs/server/namenode/ src/test/java/org/apache/hadoop/hdfs/server/namenode/snapshot/

Author: cnauroth
Date: Fri May 16 06:06:11 2014
New Revision: 1595113

URL: http://svn.apache.org/r1595113
Log:
HDFS-6414. xattr modification operations are based on state of latest snapshot instead of current version of inode. Contributed by Andrew Wang.

Modified:
    hadoop/common/branches/HDFS-2006/hadoop-hdfs-project/hadoop-hdfs/CHANGES-HDFS-2006.txt
    hadoop/common/branches/HDFS-2006/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/XAttrStorage.java
    hadoop/common/branches/HDFS-2006/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/snapshot/TestXAttrWithSnapshot.java

Modified: hadoop/common/branches/HDFS-2006/hadoop-hdfs-project/hadoop-hdfs/CHANGES-HDFS-2006.txt
URL: http://svn.apache.org/viewvc/hadoop/common/branches/HDFS-2006/hadoop-hdfs-project/hadoop-hdfs/CHANGES-HDFS-2006.txt?rev=1595113&r1=1595112&r2=1595113&view=diff
==============================================================================
--- hadoop/common/branches/HDFS-2006/hadoop-hdfs-project/hadoop-hdfs/CHANGES-HDFS-2006.txt (original)
+++ hadoop/common/branches/HDFS-2006/hadoop-hdfs-project/hadoop-hdfs/CHANGES-HDFS-2006.txt Fri May 16 06:06:11 2014
@@ -64,3 +64,6 @@ HDFS-2006 (Unreleased)
 
     HDFS-6413. xattr names erroneously handled as case-insensitive.
     (Charles Lamb via cnauroth)
+
+    HDFS-6414. xattr modification operations are based on state of latest
+    snapshot instead of current version of inode. (Andrew Wang via cnauroth)

Modified: hadoop/common/branches/HDFS-2006/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/XAttrStorage.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/HDFS-2006/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/XAttrStorage.java?rev=1595113&r1=1595112&r2=1595113&view=diff
==============================================================================
--- hadoop/common/branches/HDFS-2006/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/XAttrStorage.java (original)
+++ hadoop/common/branches/HDFS-2006/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/XAttrStorage.java Fri May 16 06:06:11 2014
@@ -60,21 +60,21 @@ public class XAttrStorage {
    * Update xattrs of inode.
    * @param inode INode to update
    * @param xAttrs to update xAttrs.
-   * @param snapshotId
+   * @param snapshotId id of the latest snapshot of the inode
    */
   public static void updateINodeXAttrs(INode inode, 
       List<XAttr> xAttrs, int snapshotId) throws QuotaExceededException {
     if (xAttrs == null || xAttrs.isEmpty()) {
-      if (inode.getXAttrFeature(snapshotId) != null) {
+      if (inode.getXAttrFeature() != null) {
         inode.removeXAttrFeature(snapshotId);
       }
       return;
     }
     
     ImmutableList<XAttr> newXAttrs = ImmutableList.copyOf(xAttrs);
-    if (inode.getXAttrFeature(snapshotId) != null) {
+    if (inode.getXAttrFeature() != null) {
       inode.removeXAttrFeature(snapshotId);
     }
-    inode.addXAttrFeature(new XAttrFeature(newXAttrs));
+    inode.addXAttrFeature(new XAttrFeature(newXAttrs), snapshotId);
   }
 }

Modified: hadoop/common/branches/HDFS-2006/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/snapshot/TestXAttrWithSnapshot.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/HDFS-2006/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/snapshot/TestXAttrWithSnapshot.java?rev=1595113&r1=1595112&r2=1595113&view=diff
==============================================================================
--- hadoop/common/branches/HDFS-2006/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/snapshot/TestXAttrWithSnapshot.java (original)
+++ hadoop/common/branches/HDFS-2006/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/snapshot/TestXAttrWithSnapshot.java Fri May 16 06:06:11 2014
@@ -18,11 +18,16 @@
 
 package org.apache.hadoop.hdfs.server.namenode.snapshot;
 
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+
+import java.util.EnumSet;
 import java.util.Map;
 
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.fs.FileSystem;
 import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.fs.XAttrSetFlag;
 import org.apache.hadoop.fs.permission.FsPermission;
 import org.apache.hadoop.hdfs.DFSConfigKeys;
 import org.apache.hadoop.hdfs.DistributedFileSystem;
@@ -86,6 +91,80 @@ public class TestXAttrWithSnapshot {
   }
 
   /**
+   * Tests modifying xattrs on a directory that has been snapshotted
+   */
+  @Test (timeout = 120000)
+  public void testModifyReadsCurrentState() throws Exception {
+    // Init
+    FileSystem.mkdirs(hdfs, path, FsPermission.createImmutable((short) 0700));
+    SnapshotTestHelper.createSnapshot(hdfs, path, snapshotName);
+    hdfs.setXAttr(path, name1, value1);
+    hdfs.setXAttr(path, name2, value2);
+
+    // Verify that current path reflects xattrs, snapshot doesn't
+    Map<String, byte[]> xattrs = hdfs.getXAttrs(path);
+    assertEquals(xattrs.size(), 2);
+    assertArrayEquals(value1, xattrs.get(name1));
+    assertArrayEquals(value2, xattrs.get(name2));
+
+    xattrs = hdfs.getXAttrs(snapshotPath);
+    assertEquals(xattrs.size(), 0);
+
+    // Modify each xattr and make sure it's reflected
+    hdfs.setXAttr(path, name1, value2, EnumSet.of(XAttrSetFlag.REPLACE));
+    xattrs = hdfs.getXAttrs(path);
+    assertEquals(xattrs.size(), 2);
+    assertArrayEquals(value2, xattrs.get(name1));
+    assertArrayEquals(value2, xattrs.get(name2));
+
+    hdfs.setXAttr(path, name2, value1, EnumSet.of(XAttrSetFlag.REPLACE));
+    xattrs = hdfs.getXAttrs(path);
+    assertEquals(xattrs.size(), 2);
+    assertArrayEquals(value2, xattrs.get(name1));
+    assertArrayEquals(value1, xattrs.get(name2));
+
+    // Paranoia checks
+    xattrs = hdfs.getXAttrs(snapshotPath);
+    assertEquals(xattrs.size(), 0);
+
+    hdfs.removeXAttr(path, name1);
+    hdfs.removeXAttr(path, name2);
+    xattrs = hdfs.getXAttrs(path);
+    assertEquals(xattrs.size(), 0);
+  }
+
+  /**
+   * Tests removing xattrs on a directory that has been snapshotted
+   */
+  @Test (timeout = 120000)
+  public void testRemoveReadsCurrentState() throws Exception {
+    // Init
+    FileSystem.mkdirs(hdfs, path, FsPermission.createImmutable((short) 0700));
+    SnapshotTestHelper.createSnapshot(hdfs, path, snapshotName);
+    hdfs.setXAttr(path, name1, value1);
+    hdfs.setXAttr(path, name2, value2);
+
+    // Verify that current path reflects xattrs, snapshot doesn't
+    Map<String, byte[]> xattrs = hdfs.getXAttrs(path);
+    assertEquals(xattrs.size(), 2);
+    assertArrayEquals(value1, xattrs.get(name1));
+    assertArrayEquals(value2, xattrs.get(name2));
+
+    xattrs = hdfs.getXAttrs(snapshotPath);
+    assertEquals(xattrs.size(), 0);
+
+    // Remove xattrs and verify one-by-one
+    hdfs.removeXAttr(path, name2);
+    xattrs = hdfs.getXAttrs(path);
+    assertEquals(xattrs.size(), 1);
+    assertArrayEquals(value1, xattrs.get(name1));
+
+    hdfs.removeXAttr(path, name1);
+    xattrs = hdfs.getXAttrs(path);
+    assertEquals(xattrs.size(), 0);
+  }
+
+  /**
    * 1) Save xattrs, then create snapshot. Assert that inode of original and
    * snapshot have same xattrs. 2) Change the original xattrs, assert snapshot
    * still has old xattrs.
@@ -215,6 +294,25 @@ public class TestXAttrWithSnapshot {
     hdfs.setXAttr(filePath, name2, value2);
   }
 
+
+  /**
+   * Test that an exception is thrown when adding an XAttr Feature to
+   * a snapshotted path
+   */
+  @Test
+  public void testSetXAttrAfterSnapshotExceedsQuota() throws Exception {
+    Path filePath = new Path(path, "file1");
+    FileSystem.mkdirs(hdfs, path, FsPermission.createImmutable((short) 0755));
+    hdfs.allowSnapshot(path);
+    hdfs.setQuota(path, 3, HdfsConstants.QUOTA_DONT_SET);
+    FileSystem.create(hdfs, filePath,
+        FsPermission.createImmutable((short) 0600)).close();
+    hdfs.createSnapshot(path, snapshotName);
+    // This adds an XAttr feature, which can throw an exception
+    exception.expect(NSQuotaExceededException.class);
+    hdfs.setXAttr(filePath, name1, value1);
+  }
+
   /**
    * Assert exception of removing xattr when exceeding quota.
    */