Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

nfsd: make 'boot_time' 64-bit wide

The local boot time variable gets truncated to time_t at the moment,
which can lead to slightly odd behavior on 32-bit architectures.

Use ktime_get_real_seconds() instead of get_seconds() to always
get a 64-bit result, and keep it that way wherever possible.

It still gets truncated in a few places:

- When assigning to cl_clientid.cl_boot, this is already documented
and is only used as a unique identifier.

- In clients_still_reclaiming(), the truncation is to 'unsigned long'
in order to use the 'time_before() helper.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>

authored by

Arnd Bergmann and committed by
J. Bruce Fields
9cc76801 e4598e38

+12 -12
+1 -1
fs/nfsd/netns.h
··· 40 40 41 41 struct lock_manager nfsd4_manager; 42 42 bool grace_ended; 43 - time_t boot_time; 43 + time64_t boot_time; 44 44 45 45 /* internal mount of the "nfsd" pseudofilesystem: */ 46 46 struct vfsmount *nfsd_mnt;
+4 -4
fs/nfsd/nfs4recover.c
··· 1445 1445 } 1446 1446 1447 1447 cup->cu_u.cu_msg.cm_cmd = Cld_GraceDone; 1448 - cup->cu_u.cu_msg.cm_u.cm_gracetime = (int64_t)nn->boot_time; 1448 + cup->cu_u.cu_msg.cm_u.cm_gracetime = nn->boot_time; 1449 1449 ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg); 1450 1450 if (!ret) 1451 1451 ret = cup->cu_u.cu_msg.cm_status; ··· 1782 1782 } 1783 1783 1784 1784 static char * 1785 - nfsd4_cltrack_grace_start(time_t grace_start) 1785 + nfsd4_cltrack_grace_start(time64_t grace_start) 1786 1786 { 1787 1787 int copied; 1788 1788 size_t len; ··· 1795 1795 if (!result) 1796 1796 return result; 1797 1797 1798 - copied = snprintf(result, len, GRACE_START_ENV_PREFIX "%ld", 1798 + copied = snprintf(result, len, GRACE_START_ENV_PREFIX "%lld", 1799 1799 grace_start); 1800 1800 if (copied >= len) { 1801 1801 /* just return nothing if output was truncated */ ··· 2004 2004 char *legacy; 2005 2005 char timestr[22]; /* FIXME: better way to determine max size? */ 2006 2006 2007 - sprintf(timestr, "%ld", nn->boot_time); 2007 + sprintf(timestr, "%lld", nn->boot_time); 2008 2008 legacy = nfsd4_cltrack_legacy_topdir(); 2009 2009 nfsd4_umh_cltrack_upcall("gracedone", timestr, legacy, NULL); 2010 2010 kfree(legacy);
+7 -7
fs/nfsd/nfs4state.c
··· 748 748 { 749 749 int new_id; 750 750 751 - stid->stid.si_opaque.so_clid.cl_boot = nn->boot_time; 751 + stid->stid.si_opaque.so_clid.cl_boot = (u32)nn->boot_time; 752 752 stid->stid.si_opaque.so_clid.cl_id = nn->s2s_cp_cl_id; 753 753 stid->sc_type = sc_type; 754 754 ··· 1911 1911 */ 1912 1912 if (clid->cl_boot == (u32)nn->boot_time) 1913 1913 return 0; 1914 - dprintk("NFSD stale clientid (%08x/%08x) boot_time %08lx\n", 1914 + dprintk("NFSD stale clientid (%08x/%08x) boot_time %08llx\n", 1915 1915 clid->cl_boot, clid->cl_id, nn->boot_time); 1916 1916 return 1; 1917 1917 } ··· 2271 2271 2272 2272 static void gen_clid(struct nfs4_client *clp, struct nfsd_net *nn) 2273 2273 { 2274 - clp->cl_clientid.cl_boot = nn->boot_time; 2274 + clp->cl_clientid.cl_boot = (u32)nn->boot_time; 2275 2275 clp->cl_clientid.cl_id = nn->clientid_counter++; 2276 2276 gen_confirm(clp, nn); 2277 2277 } ··· 5233 5233 */ 5234 5234 static bool clients_still_reclaiming(struct nfsd_net *nn) 5235 5235 { 5236 - unsigned long now = get_seconds(); 5237 - unsigned long double_grace_period_end = nn->boot_time + 5238 - 2 * nn->nfsd4_lease; 5236 + unsigned long now = (unsigned long) ktime_get_real_seconds(); 5237 + unsigned long double_grace_period_end = (unsigned long)nn->boot_time + 5238 + 2 * (unsigned long)nn->nfsd4_lease; 5239 5239 5240 5240 if (nn->track_reclaim_completes && 5241 5241 atomic_read(&nn->nr_reclaim_complete) == ··· 7792 7792 INIT_LIST_HEAD(&nn->sessionid_hashtbl[i]); 7793 7793 nn->conf_name_tree = RB_ROOT; 7794 7794 nn->unconf_name_tree = RB_ROOT; 7795 - nn->boot_time = get_seconds(); 7795 + nn->boot_time = ktime_get_real_seconds(); 7796 7796 nn->grace_ended = false; 7797 7797 nn->nfsd4_manager.block_opens = true; 7798 7798 INIT_LIST_HEAD(&nn->nfsd4_manager.list);