aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/xfs_log.c226
1 files changed, 120 insertions, 106 deletions
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
index 4a0ec592564c..8c856d24538c 100644
--- a/fs/xfs/xfs_log.c
+++ b/fs/xfs/xfs_log.c
@@ -1866,127 +1866,141 @@ xlog_write(
1866 struct xlog_in_core **commit_iclog, 1866 struct xlog_in_core **commit_iclog,
1867 uint flags) 1867 uint flags)
1868{ 1868{
1869 xlog_t *log = mp->m_log; 1869 struct log *log = mp->m_log;
1870 xlog_in_core_t *iclog = NULL; /* ptr to current in-core log */ 1870 struct xlog_in_core *iclog = NULL;
1871 xlog_op_header_t *logop_head; /* ptr to log operation header */ 1871 int len;
1872 __psint_t ptr; /* copy address into data region */ 1872 int index;
1873 int len; /* # xlog_write() bytes 2 still copy */ 1873 int partial_copy = 0;
1874 int index; /* region index currently copying */ 1874 int partial_copy_len = 0;
1875 int log_offset; /* offset (from 0) into data region */ 1875 int contwr = 0;
1876 int start_rec_copy; /* # bytes to copy for start record */ 1876 int record_cnt = 0;
1877 int partial_copy; /* did we split a region? */ 1877 int data_cnt = 0;
1878 int partial_copy_len;/* # bytes copied if split region */ 1878 int error;
1879 int copy_len; /* # bytes actually memcpy'ing */ 1879
1880 int copy_off; /* # bytes from entry start */ 1880 *start_lsn = 0;
1881 int contwr; /* continued write of in-core log? */ 1881
1882 int error; 1882 len = xlog_write_calc_vec_length(ticket, reg, nentries);
1883 int record_cnt = 0, data_cnt = 0; 1883 if (ticket->t_curr_res < len) {
1884 1884 xlog_print_tic_res(mp, ticket);
1885 partial_copy_len = partial_copy = 0;
1886 contwr = *start_lsn = 0;
1887
1888 len = xlog_write_calc_vec_length(ticket, reg, nentries);
1889 if (ticket->t_curr_res < len) {
1890 xlog_print_tic_res(mp, ticket);
1891#ifdef DEBUG 1885#ifdef DEBUG
1892 xlog_panic( 1886 xlog_panic(
1893 "xfs_log_write: reservation ran out. Need to up reservation"); 1887 "xfs_log_write: reservation ran out. Need to up reservation");
1894#else 1888#else
1895 /* Customer configurable panic */ 1889 /* Customer configurable panic */
1896 xfs_cmn_err(XFS_PTAG_LOGRES, CE_ALERT, mp, 1890 xfs_cmn_err(XFS_PTAG_LOGRES, CE_ALERT, mp,
1897 "xfs_log_write: reservation ran out. Need to up reservation"); 1891 "xfs_log_write: reservation ran out. Need to up reservation");
1898 /* If we did not panic, shutdown the filesystem */ 1892
1899 xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE); 1893 /* If we did not panic, shutdown the filesystem */
1894 xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
1900#endif 1895#endif
1901 } else 1896 }
1897
1902 ticket->t_curr_res -= len; 1898 ticket->t_curr_res -= len;
1903 1899
1904 for (index = 0; index < nentries; ) { 1900 for (index = 0; index < nentries; ) {
1905 if ((error = xlog_state_get_iclog_space(log, len, &iclog, ticket, 1901 __psint_t ptr;
1906 &contwr, &log_offset))) 1902 int log_offset;
1907 return error;
1908 1903
1909 ASSERT(log_offset <= iclog->ic_size - 1); 1904 error = xlog_state_get_iclog_space(log, len, &iclog, ticket,
1910 ptr = (__psint_t) ((char *)iclog->ic_datap+log_offset); 1905 &contwr, &log_offset);
1906 if (error)
1907 return error;
1911 1908
1912 /* start_lsn is the first lsn written to. That's all we need. */ 1909 ASSERT(log_offset <= iclog->ic_size - 1);
1913 if (! *start_lsn) 1910 ptr = (__psint_t)((char *)iclog->ic_datap + log_offset);
1914 *start_lsn = be64_to_cpu(iclog->ic_header.h_lsn);
1915 1911
1916 /* This loop writes out as many regions as can fit in the amount 1912 /* start_lsn is the first lsn written to. That's all we need. */
1917 * of space which was allocated by xlog_state_get_iclog_space(). 1913 if (!*start_lsn)
1918 */ 1914 *start_lsn = be64_to_cpu(iclog->ic_header.h_lsn);
1919 while (index < nentries) {
1920 ASSERT(reg[index].i_len % sizeof(__int32_t) == 0);
1921 ASSERT((__psint_t)ptr % sizeof(__int32_t) == 0);
1922
1923 start_rec_copy = xlog_write_start_rec(ptr, ticket);
1924 if (start_rec_copy) {
1925 record_cnt++;
1926 xlog_write_adv_cnt(ptr, len, log_offset, start_rec_copy);
1927 }
1928 1915
1929 logop_head = xlog_write_setup_ophdr(log, ptr, ticket, flags); 1916 /*
1930 if (!logop_head) 1917 * This loop writes out as many regions as can fit in the amount
1931 return XFS_ERROR(EIO); 1918 * of space which was allocated by xlog_state_get_iclog_space().
1932 xlog_write_adv_cnt(ptr, len, log_offset, sizeof(xlog_op_header_t)); 1919 */
1933 1920 while (index < nentries) {
1934 len += xlog_write_setup_copy(ticket, logop_head, 1921 struct xlog_op_header *ophdr;
1935 iclog->ic_size - log_offset, 1922 int start_rec_copy;
1936 reg[index].i_len, &copy_off, 1923 int copy_len;
1937 &copy_len, &partial_copy, 1924 int copy_off;
1938 &partial_copy_len); 1925
1939 xlog_verify_dest_ptr(log, ptr); 1926 ASSERT(reg[index].i_len % sizeof(__int32_t) == 0);
1940 1927 ASSERT((__psint_t)ptr % sizeof(__int32_t) == 0);
1941 /* copy region */ 1928
1942 ASSERT(copy_len >= 0); 1929 start_rec_copy = xlog_write_start_rec(ptr, ticket);
1943 memcpy((xfs_caddr_t)ptr, reg[index].i_addr + copy_off, copy_len); 1930 if (start_rec_copy) {
1944 xlog_write_adv_cnt(ptr, len, log_offset, copy_len); 1931 record_cnt++;
1945 1932 xlog_write_adv_cnt(ptr, len, log_offset,
1946 /* make copy_len total bytes copied, including headers */ 1933 start_rec_copy);
1947 copy_len += start_rec_copy + sizeof(xlog_op_header_t); 1934 }
1948 record_cnt++;
1949 data_cnt += contwr ? copy_len : 0;
1950
1951 error = xlog_write_copy_finish(log, iclog, flags,
1952 &record_cnt, &data_cnt,
1953 &partial_copy, &partial_copy_len,
1954 log_offset, commit_iclog);
1955 if (error)
1956 return error;
1957 1935
1958 /* 1936 ophdr = xlog_write_setup_ophdr(log, ptr, ticket, flags);
1959 * if we had a partial copy, we need to get more iclog 1937 if (!ophdr)
1960 * space but we don't want to increment the region 1938 return XFS_ERROR(EIO);
1961 * index because there is still more is this region to write.
1962 *
1963 * If we completed writing this region, and we flushed
1964 * the iclog (indicated by resetting of the record
1965 * count), then we also need to get more log space. If
1966 * this was the last record, though, we are done and
1967 * can just return.
1968 */
1969 if (partial_copy)
1970 break;
1971 1939
1972 index++; 1940 xlog_write_adv_cnt(ptr, len, log_offset,
1973 if (record_cnt == 0) { 1941 sizeof(struct xlog_op_header));
1974 if (index == nentries) 1942
1975 return 0; 1943 len += xlog_write_setup_copy(ticket, ophdr,
1976 break; 1944 iclog->ic_size-log_offset,
1977 } 1945 reg[index].i_len,
1978 } /* while (index < nentries) */ 1946 &copy_off, &copy_len,
1979 } /* for (index = 0; index < nentries; ) */ 1947 &partial_copy,
1980 ASSERT(len == 0); 1948 &partial_copy_len);
1949 xlog_verify_dest_ptr(log, ptr);
1950
1951 /* copy region */
1952 ASSERT(copy_len >= 0);
1953 memcpy((xfs_caddr_t)ptr, reg[index].i_addr + copy_off,
1954 copy_len);
1955 xlog_write_adv_cnt(ptr, len, log_offset, copy_len);
1956
1957 copy_len += start_rec_copy + sizeof(xlog_op_header_t);
1958 record_cnt++;
1959 data_cnt += contwr ? copy_len : 0;
1960
1961 error = xlog_write_copy_finish(log, iclog, flags,
1962 &record_cnt, &data_cnt,
1963 &partial_copy,
1964 &partial_copy_len,
1965 log_offset,
1966 commit_iclog);
1967 if (error)
1968 return error;
1969
1970 /*
1971 * if we had a partial copy, we need to get more iclog
1972 * space but we don't want to increment the region
1973 * index because there is still more is this region to
1974 * write.
1975 *
1976 * If we completed writing this region, and we flushed
1977 * the iclog (indicated by resetting of the record
1978 * count), then we also need to get more log space. If
1979 * this was the last record, though, we are done and
1980 * can just return.
1981 */
1982 if (partial_copy)
1983 break;
1984
1985 index++;
1986 if (record_cnt == 0) {
1987 if (index == nentries)
1988 return 0;
1989 break;
1990 }
1991 }
1992 }
1993
1994 ASSERT(len == 0);
1995
1996 xlog_state_finish_copy(log, iclog, record_cnt, data_cnt);
1997 if (!commit_iclog)
1998 return xlog_state_release_iclog(log, iclog);
1981 1999
1982 xlog_state_finish_copy(log, iclog, record_cnt, data_cnt);
1983 if (commit_iclog) {
1984 ASSERT(flags & XLOG_COMMIT_TRANS); 2000 ASSERT(flags & XLOG_COMMIT_TRANS);
1985 *commit_iclog = iclog; 2001 *commit_iclog = iclog;
1986 return 0; 2002 return 0;
1987 } 2003}
1988 return xlog_state_release_iclog(log, iclog);
1989} /* xlog_write */
1990 2004
1991 2005
1992/***************************************************************************** 2006/*****************************************************************************