aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/xattr.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ocfs2/xattr.c')
-rw-r--r--fs/ocfs2/xattr.c140
1 files changed, 124 insertions, 16 deletions
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c
index a2d912a92dd7..d1b0d386f6d1 100644
--- a/fs/ocfs2/xattr.c
+++ b/fs/ocfs2/xattr.c
@@ -1869,6 +1869,17 @@ static const struct ocfs2_xa_loc_operations ocfs2_xa_bucket_loc_ops = {
1869 .xlo_fill_value_buf = ocfs2_xa_bucket_fill_value_buf, 1869 .xlo_fill_value_buf = ocfs2_xa_bucket_fill_value_buf,
1870}; 1870};
1871 1871
1872static unsigned int ocfs2_xa_value_clusters(struct ocfs2_xa_loc *loc)
1873{
1874 struct ocfs2_xattr_value_buf vb;
1875
1876 if (ocfs2_xattr_is_local(loc->xl_entry))
1877 return 0;
1878
1879 ocfs2_xa_fill_value_buf(loc, &vb);
1880 return le32_to_cpu(vb.vb_xv->xr_clusters);
1881}
1882
1872static int ocfs2_xa_value_truncate(struct ocfs2_xa_loc *loc, u64 bytes, 1883static int ocfs2_xa_value_truncate(struct ocfs2_xa_loc *loc, u64 bytes,
1873 struct ocfs2_xattr_set_ctxt *ctxt) 1884 struct ocfs2_xattr_set_ctxt *ctxt)
1874{ 1885{
@@ -1923,16 +1934,85 @@ static void ocfs2_xa_remove_entry(struct ocfs2_xa_loc *loc)
1923 } 1934 }
1924} 1935}
1925 1936
1937/*
1938 * If we have a problem adjusting the size of an external value during
1939 * ocfs2_xa_prepare_entry() or ocfs2_xa_remove(), we may have an xattr
1940 * in an intermediate state. For example, the value may be partially
1941 * truncated.
1942 *
1943 * If the value tree hasn't changed, the extend/truncate went nowhere.
1944 * We have nothing to do. The caller can treat it as a straight error.
1945 *
1946 * If the value tree got partially truncated, we now have a corrupted
1947 * extended attribute. We're going to wipe its entry and leak the
1948 * clusters. Better to leak some storage than leave a corrupt entry.
1949 *
1950 * If the value tree grew, it obviously didn't grow enough for the
1951 * new entry. We're not going to try and reclaim those clusters either.
1952 * If there was already an external value there (orig_clusters != 0),
1953 * the new clusters are attached safely and we can just leave the old
1954 * value in place. If there was no external value there, we remove
1955 * the entry.
1956 *
1957 * This way, the xattr block we store in the journal will be consistent.
1958 * If the size change broke because of the journal, no changes will hit
1959 * disk anyway.
1960 */
1961static void ocfs2_xa_cleanup_value_truncate(struct ocfs2_xa_loc *loc,
1962 const char *what,
1963 unsigned int orig_clusters)
1964{
1965 unsigned int new_clusters = ocfs2_xa_value_clusters(loc);
1966 char *nameval_buf = ocfs2_xa_offset_pointer(loc,
1967 le16_to_cpu(loc->xl_entry->xe_name_offset));
1968
1969 if (new_clusters < orig_clusters) {
1970 mlog(ML_ERROR,
1971 "Partial truncate while %s xattr %.*s. Leaking "
1972 "%u clusters and removing the entry\n",
1973 what, loc->xl_entry->xe_name_len, nameval_buf,
1974 orig_clusters - new_clusters);
1975 ocfs2_xa_remove_entry(loc);
1976 } else if (!orig_clusters) {
1977 mlog(ML_ERROR,
1978 "Unable to allocate an external value for xattr "
1979 "%.*s safely. Leaking %u clusters and removing the "
1980 "entry\n",
1981 loc->xl_entry->xe_name_len, nameval_buf,
1982 new_clusters - orig_clusters);
1983 ocfs2_xa_remove_entry(loc);
1984 } else if (new_clusters > orig_clusters)
1985 mlog(ML_ERROR,
1986 "Unable to grow xattr %.*s safely. %u new clusters "
1987 "have been added, but the value will not be "
1988 "modified\n",
1989 loc->xl_entry->xe_name_len, nameval_buf,
1990 new_clusters - orig_clusters);
1991}
1992
1926static int ocfs2_xa_remove(struct ocfs2_xa_loc *loc, 1993static int ocfs2_xa_remove(struct ocfs2_xa_loc *loc,
1927 struct ocfs2_xattr_set_ctxt *ctxt) 1994 struct ocfs2_xattr_set_ctxt *ctxt)
1928{ 1995{
1929 int rc = 0; 1996 int rc = 0;
1997 unsigned int orig_clusters;
1930 1998
1931 if (!ocfs2_xattr_is_local(loc->xl_entry)) { 1999 if (!ocfs2_xattr_is_local(loc->xl_entry)) {
2000 orig_clusters = ocfs2_xa_value_clusters(loc);
1932 rc = ocfs2_xa_value_truncate(loc, 0, ctxt); 2001 rc = ocfs2_xa_value_truncate(loc, 0, ctxt);
1933 if (rc) { 2002 if (rc) {
1934 mlog_errno(rc); 2003 mlog_errno(rc);
1935 goto out; 2004 /*
2005 * Since this is remove, we can return 0 if
2006 * ocfs2_xa_cleanup_value_truncate() is going to
2007 * wipe the entry anyway. So we check the
2008 * cluster count as well.
2009 */
2010 if (orig_clusters != ocfs2_xa_value_clusters(loc))
2011 rc = 0;
2012 ocfs2_xa_cleanup_value_truncate(loc, "removing",
2013 orig_clusters);
2014 if (rc)
2015 goto out;
1936 } 2016 }
1937 } 2017 }
1938 2018
@@ -1963,6 +2043,7 @@ static int ocfs2_xa_reuse_entry(struct ocfs2_xa_loc *loc,
1963{ 2043{
1964 int rc = 0; 2044 int rc = 0;
1965 int name_size = OCFS2_XATTR_SIZE(xi->xi_name_len); 2045 int name_size = OCFS2_XATTR_SIZE(xi->xi_name_len);
2046 unsigned int orig_clusters;
1966 char *nameval_buf; 2047 char *nameval_buf;
1967 int xe_local = ocfs2_xattr_is_local(loc->xl_entry); 2048 int xe_local = ocfs2_xattr_is_local(loc->xl_entry);
1968 int xi_local = xi->xi_value_len <= OCFS2_XATTR_INLINE_SIZE; 2049 int xi_local = xi->xi_value_len <= OCFS2_XATTR_INLINE_SIZE;
@@ -1978,23 +2059,27 @@ static int ocfs2_xa_reuse_entry(struct ocfs2_xa_loc *loc,
1978 if (!xi_local) 2059 if (!xi_local)
1979 ocfs2_xa_install_value_root(loc); 2060 ocfs2_xa_install_value_root(loc);
1980 } else { 2061 } else {
2062 orig_clusters = ocfs2_xa_value_clusters(loc);
1981 if (xi_local) { 2063 if (xi_local) {
1982 rc = ocfs2_xa_value_truncate(loc, 0, ctxt); 2064 rc = ocfs2_xa_value_truncate(loc, 0, ctxt);
1983 if (rc < 0) { 2065 if (rc < 0)
1984 mlog_errno(rc); 2066 mlog_errno(rc);
1985 goto out; 2067 else
1986 } 2068 memset(nameval_buf + name_size, 0,
1987 memset(nameval_buf + name_size, 0, 2069 namevalue_size_xe(loc->xl_entry) -
1988 namevalue_size_xe(loc->xl_entry) - 2070 name_size);
1989 name_size);
1990 } else if (le64_to_cpu(loc->xl_entry->xe_value_size) > 2071 } else if (le64_to_cpu(loc->xl_entry->xe_value_size) >
1991 xi->xi_value_len) { 2072 xi->xi_value_len) {
1992 rc = ocfs2_xa_value_truncate(loc, xi->xi_value_len, 2073 rc = ocfs2_xa_value_truncate(loc, xi->xi_value_len,
1993 ctxt); 2074 ctxt);
1994 if (rc < 0) { 2075 if (rc < 0)
1995 mlog_errno(rc); 2076 mlog_errno(rc);
1996 goto out; 2077 }
1997 } 2078
2079 if (rc) {
2080 ocfs2_xa_cleanup_value_truncate(loc, "reusing",
2081 orig_clusters);
2082 goto out;
1998 } 2083 }
1999 } 2084 }
2000 2085
@@ -2019,6 +2104,8 @@ static int ocfs2_xa_prepare_entry(struct ocfs2_xa_loc *loc,
2019 struct ocfs2_xattr_set_ctxt *ctxt) 2104 struct ocfs2_xattr_set_ctxt *ctxt)
2020{ 2105{
2021 int rc = 0; 2106 int rc = 0;
2107 unsigned int orig_clusters;
2108 __le64 orig_value_size = 0;
2022 2109
2023 rc = ocfs2_xa_check_space(loc, xi); 2110 rc = ocfs2_xa_check_space(loc, xi);
2024 if (rc) 2111 if (rc)
@@ -2026,6 +2113,7 @@ static int ocfs2_xa_prepare_entry(struct ocfs2_xa_loc *loc,
2026 2113
2027 if (loc->xl_entry) { 2114 if (loc->xl_entry) {
2028 if (ocfs2_xa_can_reuse_entry(loc, xi)) { 2115 if (ocfs2_xa_can_reuse_entry(loc, xi)) {
2116 orig_value_size = loc->xl_entry->xe_value_size;
2029 rc = ocfs2_xa_reuse_entry(loc, xi, ctxt); 2117 rc = ocfs2_xa_reuse_entry(loc, xi, ctxt);
2030 if (rc) 2118 if (rc)
2031 goto out; 2119 goto out;
@@ -2033,9 +2121,13 @@ static int ocfs2_xa_prepare_entry(struct ocfs2_xa_loc *loc,
2033 } 2121 }
2034 2122
2035 if (!ocfs2_xattr_is_local(loc->xl_entry)) { 2123 if (!ocfs2_xattr_is_local(loc->xl_entry)) {
2124 orig_clusters = ocfs2_xa_value_clusters(loc);
2036 rc = ocfs2_xa_value_truncate(loc, 0, ctxt); 2125 rc = ocfs2_xa_value_truncate(loc, 0, ctxt);
2037 if (rc) { 2126 if (rc) {
2038 mlog_errno(rc); 2127 mlog_errno(rc);
2128 ocfs2_xa_cleanup_value_truncate(loc,
2129 "overwriting",
2130 orig_clusters);
2039 goto out; 2131 goto out;
2040 } 2132 }
2041 } 2133 }
@@ -2053,9 +2145,20 @@ static int ocfs2_xa_prepare_entry(struct ocfs2_xa_loc *loc,
2053 2145
2054alloc_value: 2146alloc_value:
2055 if (xi->xi_value_len > OCFS2_XATTR_INLINE_SIZE) { 2147 if (xi->xi_value_len > OCFS2_XATTR_INLINE_SIZE) {
2148 orig_clusters = ocfs2_xa_value_clusters(loc);
2056 rc = ocfs2_xa_value_truncate(loc, xi->xi_value_len, ctxt); 2149 rc = ocfs2_xa_value_truncate(loc, xi->xi_value_len, ctxt);
2057 if (rc < 0) 2150 if (rc < 0) {
2151 /*
2152 * If we tried to grow an existing external value,
2153 * ocfs2_xa_cleanuP-value_truncate() is going to
2154 * let it stand. We have to restore its original
2155 * value size.
2156 */
2157 loc->xl_entry->xe_value_size = orig_value_size;
2158 ocfs2_xa_cleanup_value_truncate(loc, "growing",
2159 orig_clusters);
2058 mlog_errno(rc); 2160 mlog_errno(rc);
2161 }
2059 } 2162 }
2060 2163
2061out: 2164out:
@@ -2105,25 +2208,30 @@ static int ocfs2_xa_set(struct ocfs2_xa_loc *loc,
2105 goto out; 2208 goto out;
2106 } 2209 }
2107 2210
2211 /*
2212 * From here on out, everything is going to modify the buffer a
2213 * little. Errors are going to leave the xattr header in a
2214 * sane state. Thus, even with errors we dirty the sucker.
2215 */
2216
2108 /* Don't worry, we are never called with !xi_value and !xl_entry */ 2217 /* Don't worry, we are never called with !xi_value and !xl_entry */
2109 if (!xi->xi_value) { 2218 if (!xi->xi_value) {
2110 ret = ocfs2_xa_remove(loc, ctxt); 2219 ret = ocfs2_xa_remove(loc, ctxt);
2111 goto out; 2220 goto out_dirty;
2112 } 2221 }
2113 2222
2114 ret = ocfs2_xa_prepare_entry(loc, xi, name_hash, ctxt); 2223 ret = ocfs2_xa_prepare_entry(loc, xi, name_hash, ctxt);
2115 if (ret) { 2224 if (ret) {
2116 if (ret != -ENOSPC) 2225 if (ret != -ENOSPC)
2117 mlog_errno(ret); 2226 mlog_errno(ret);
2118 goto out; 2227 goto out_dirty;
2119 } 2228 }
2120 2229
2121 ret = ocfs2_xa_store_value(loc, xi, ctxt); 2230 ret = ocfs2_xa_store_value(loc, xi, ctxt);
2122 if (ret) { 2231 if (ret)
2123 mlog_errno(ret); 2232 mlog_errno(ret);
2124 goto out;
2125 }
2126 2233
2234out_dirty:
2127 ocfs2_xa_journal_dirty(ctxt->handle, loc); 2235 ocfs2_xa_journal_dirty(ctxt->handle, loc);
2128 2236
2129out: 2237out: